import { PiniaPluginContext, StateTree, SubscriptionCallbackMutation } from 'pinia';
import { UnwrapRef, toRaw } from 'vue';

export const PERSIST_METHOD_NAME = '__cn__persist';

export const createCnPiniaPlugin = () => {
  return (context: PiniaPluginContext) => {
    console.log('');
    /**
     * 这里会为每个 store 执行一次
     */
    const { options, store, pinia } = context;

    console.log('createCnPiniaPlugin >>> options =', options);

    const storeId = store.$id;

    console.log('createCnPiniaPlugin >>> storeId =', storeId);

    // HMR handling, ignores stores created as "hot" stores
    /* c8 ignore start */
    if (!(storeId in pinia.state.value)) {
      // @ts-expect-error `_s is a stripped @internal`
      const original_store = pinia._s.get(storeId.replace('__hot:', ''));
      if (original_store) {
        Promise.resolve().then(() => original_store.$persist());
      }
      return;
    }
    /* c8 ignore stop */

    const storeState = toRaw(store.$state);

    watch(
      store.$state['recordUserField']['1'],
      (newValue, oldValue) => {
        console.log('');
        console.log('cnPiniaPlugin watch >>> oldValue =', JSON.stringify(oldValue.age));
        console.log('cnPiniaPlugin watch >>> newValue =', JSON.stringify(newValue.age));
      },
      { deep: true },
    );

    console.log('createCnPiniaPlugin >>> store.$state =', store.$state);
    console.log('createCnPiniaPlugin >>> storeState =', storeState);

    store.$subscribe(
      (mutation: SubscriptionCallbackMutation<StateTree>, state: UnwrapRef<StateTree>) => {
        console.log('');
        console.log('mutation =', mutation);
        console.log('mutation.type =', mutation.type);
        console.log('state =', state);

        const events = mutation.events;

        console.log('events =', events);

        if (!Array.isArray(events)) {
          console.log('events.key =', events.key);
          console.log('events.oldTarget =', JSON.stringify(events.oldTarget));
          console.log('events.target =', JSON.stringify(events.target));
          console.log('events.newValue =', JSON.stringify(events.newValue));
        }
      },
      { deep: true },
    );

    return {};
  };
};
